﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace YArchitech.MEP
{
	public class HYSystem : Dictionary<int, HYComponent>
	{
		public int Id { get; set; }

		public string Name { get; set; }

		public string ErrorString { get; set; }

		public HYComponent First
		{
			get
			{
				return this.m_First;
			}
			set
			{
				this.m_First = value;
			}
		}

		public IEnumerable<HYComponent> Objects
		{
			get
			{
				return base.Values;
			}
		}

		public IEnumerable<int> Ids
		{
			get
			{
				return base.Keys;
			}
		}

		public IEnumerable<HYComponent> Terminals
		{
			get
			{
				if (this.m_Terminals == null)
				{
					this.GetAllTerminals();
				}
				return this.m_Terminals;
			}
		}

		public IEnumerable<HYBranch> Branches
		{
			get
			{
				if (this.m_Branches == null)
				{
					this.GetAllBranches();
				}
				return this.m_Branches;
			}
		}

		public IEnumerable<HYTube> Tubes
		{
			get
			{
				if (this.m_Tubes == null)
				{
					this.GetAllTubes();
				}
				return this.m_Tubes;
			}
		}

		public static HYSystem ConstructSystem(HYComponent firstComp)
		{
			HYSystem result;
			try
			{
				HYSystem hysystem = new HYSystem();
				hysystem.First = firstComp;
				firstComp.AddToSystem(hysystem);
				result = hysystem;
			}
			catch
			{
				result = null;
			}
			return result;
		}

		public void Add(HYComponent comp)
		{
			if (base.ContainsKey(comp.Id))
			{
				base[comp.Id] = comp;
				return;
			}
			base.Add(comp.Id, comp);
		}

		public bool Contains(HYComponent comp)
		{
			return base.ContainsKey(comp.Id);
		}

		public bool Contains(int id)
		{
			return base.ContainsKey(id);
		}

		public HYComponent GetComponentById(int id)
		{
			HYComponent result;
			try
			{
				result = base[id];
			}
			catch
			{
				result = null;
			}
			return result;
		}

		public HYComponent GetComponentByIndex(int index)
		{
			HYComponent result;
			try
			{
				result = (from c in base.Values
				where c.Index == index
				select c).First<HYComponent>();
			}
			catch
			{
				result = null;
			}
			return result;
		}

		protected virtual void GetAllTerminals()
		{
			this.m_Terminals = from t in base.Values
			where t.IsTerminal
			select t;
		}

		protected virtual void GetAllTubes()
		{
			this.m_Tubes = from t in base.Values
			where t is HYTube
			orderby t.Index
			select t as HYTube;
		}

		public virtual void GetAllBranches()
		{
			IEnumerable<HYComponent> terminals = this.Terminals;
			List<HYBranch> list = new List<HYBranch>();
			foreach (HYComponent terminal in terminals)
			{
				list.Add(HYBranch.BuildBranch(terminal));
			}
			list.Sort(new HYBranchLengthComparer());
			int num = 1;
			foreach (HYBranch hybranch in list)
			{
				hybranch.Index = num++;
			}
			this.m_Branches = list;
		}

		public HYBranch GetLongestBranch()
		{
			HYBranch result;
			try
			{
				result = (from branch in this.Branches
				orderby branch.Length descending
				select branch).First<HYBranch>();
			}
			catch
			{
				result = null;
			}
			return result;
		}

		public HYBranch GetMaxResistanceBranch()
		{
			HYBranch result;
			try
			{
				result = (from branch in this.m_Branches
				orderby branch.Resistance descending
				select branch).First<HYBranch>();
			}
			catch
			{
				result = null;
			}
			return result;
		}

		public HYBranch GetMostUnbalancedBranch()
		{
			HYBranch result;
			try
			{
				result = (from branch in this.m_Branches
				orderby branch.UnbalanceRate descending
				select branch).First<HYBranch>();
			}
			catch
			{
				result = null;
			}
			return result;
		}

		public virtual void BuildIndex()
		{
			int num = 1;
			if (this.m_First != null)
			{
				this.m_First.RebuildIndex(ref num);
			}
		}

		public virtual void ReAllocateFlow()
		{
			if (this.m_First != null)
			{
				this.m_First.ReAllocateFlow();
			}
		}

		public virtual bool Design(HYSystemOption option)
		{
			if (this.m_First == null || option == null)
			{
				return false;
			}
			this.m_First.ReAllocateFlow();
			return true;
		}

		public virtual bool Check(HYSystemOption option)
		{
			if (this.m_First == null || option == null)
			{
				return false;
			}
			this.m_First.ReAllocateFlow();
			foreach (HYTube hytube in this.Tubes)
			{
				hytube.CalVelocity();
			}
			this.CalAttachedObjects(option);
			foreach (HYTube hytube2 in this.Tubes)
			{
				hytube2.Cal(option);
			}
			return true;
		}

		public void CalAttachedObjects(HYSystemOption option)
		{
			foreach (HYComponent hycomponent in from att in base.Values
			where !(att is HYTube)
			select att)
			{
				hycomponent.Cal(option);
			}
		}

		public virtual void CalBranch()
		{
			foreach (HYBranch hybranch in this.m_Branches)
			{
				hybranch.Cal();
			}
			HYBranch maxResistanceBranch = this.GetMaxResistanceBranch();
			foreach (HYBranch hybranch2 in this.m_Branches)
			{
				hybranch2.CalUnbalanceRate(maxResistanceBranch.Resistance);
			}
		}

		protected HYComponent m_First;

		protected IEnumerable<HYComponent> m_Terminals;

		protected IEnumerable<HYBranch> m_Branches;

		protected IEnumerable<HYTube> m_Tubes;
	}
}
